<?php
declare (strict_types=1);

namespace app\common\tool\Swoole\Server;

class Server
{
    public $server;

    public $log_file;

    public function __construct()
    {
        $config = config('server');
        $this->log_file = $config['log_file'];
        $this->server = new \Swoole\Server($config['host'], $config['port']);
        $this->server->on('connect', [$this, 'onConnect']);
        $this->server->on('close', [$this, 'onClose']);
        $this->server->on('receive', [$this, 'onReceive']);
        $this->server->on('task', [$this, 'onTask']);
        $this->server->on('finish', [$this, 'onFinish']);
        $this->server->set([
            'worker_num'      => $config['worker_num'],
            'daemonize'       => $config['daemonize'],
            'log_file'        => $this->log_file,
            'task_worker_num' => $config['task_worker_num']
        ]);
        $this->server->start();
    }

    public function onReceive($server, $fd, $reactor_id, $data)
    {
        $this->writeLog('收到任务，参数：' . json_encode($data));
        $data = json_decode($data, true);
        $server->task($data);
        $server->close($fd);
    }

    public function onTask($server, $task_id, $reactor_id, $data)
    {
        $this->writeLog('已投递Task，执行中：' . json_encode($data));
        $class = $data['class'];
        $action = $data['action'];
        $result = $class::$action($data['arguments']);
        $server->finish($result);
    }

    public function onFinish($server, $task_id, $data)
    {
        $this->writeLog('执行完成，taskID：' . $task_id . json_encode($data));
    }

    public function writeLog($msg)
    {
        file_put_contents($this->log_file, '['.date('Y-m-d H:i:s').'] ' . $msg . "\r\n", FILE_APPEND);
    }

    /**
     * 监听websocket的打开连接事件
     * @param $server
     * @param $request
     */
    public function onConnect($server, $fd)
    {
        echo "server: handshake success with fd" . $fd;
    }


    /**
     * 监听websocket的关闭连接事件
     * @param $server
     * @param $fd
     */
    public function onClose($server, $fd)
    {
        echo "client {$fd} closed\n";
    }
}
